home *** CD-ROM | disk | FTP | other *** search
- ;
- ; Program DSCOPE1
- ; copyright (C) 1983 Peter G. Aitken
- ; Department of Physiology
- ; Duke University Medical Center, Durham, NC 27710
- ;
- ; This program collects and averages sweeps of analog data from
- ; channel 0 of the labmaster board, with each sweep triggered
- ; by a pulse on channel 7. It requires that the calling program set
- ; up clock 5 to output pulses at the desired sampling rate, and
- ; that the Labmaster be jumpered for external start a/d conversions.
- ; The calling program must also pass two parameters: the address of the
- ; array for data storage, and the number of sweeps to be averaged.
- ; Program now collects 640 points/sweep. Subroutine "beep" beeps the
- ; speaker after each sweep. Maximum sampling rate=40kHz.
- ;
- sseg segment stack ;set up stack.
- dw 20 DUP (?)
- sseg ends
- ;
- dseg segment ;set up data segment.
- array dw (?)
- nswps dw (?)
- dseg ends
- ;
- cseg segment public 'CODE' ;code segment.
- ;
- assume cs:cseg,ss:sseg,ds:dseg
- ;
- public dscope1 ;declare "dscope1" public so it can
- ;be called from another program.
- dscope1 proc far
- push bp ;save register.
- mov bp,sp
- mov si,[bp]+8 ;get first parameter passed by
- ;calling program.
- mov dx,[si]
- mov array,dx ;data array address in "array".
- mov si,[bp]+6 ;get second parameter passed.
- mov dx,[si]
- mov nswps,dx ;# sweeps in nswps.
- inc nswps ;now nswps=#sweeps+1.
- ;
- ;now we go thru the array and zero all elements.
- ;
- mov bx,array ;bx points at base of array.
- mov si,0 ;si indexes array element.
- mov cx,640 ;cx counts array elements.
- mov ax,0
- zero_loop: mov [bx][si],ax ;move "0" to array element.
- add si,2 ;point at next element.
- loop zero_loop ;loop back if cx<>0.
- ;
- ;now we wait for a synch pulse on a/d channel 7.
- ;
- synch_loop: nop
- dec nswps ;nswps now = # sweeps remaining.
- jz done ;if it's 0, we're done.
- ;
- wait_synch: mov dx,0714H ;point at control byte.
- mov al,10000000B ;disable autoincrement and
- out dx,al ;all interrupts.
- inc dx ;point at a/d channel byte and
- mov al,7 ;specify that next channel
- out dx,al ;to convert is #7.
- inc dx ;point at a/d start & hi data.
- in al,dx ;read high data to reset
- ;done bit.
- out dx,al ;start a conversion.
- mov dx,0714H ;point dx at status byte
- wait_done: in al,dx ;and read it in.
- cmp al,10000000B ;see if bit 7 is set.
- jb wait_done ;if not, look again.
- inc dx ;point at low data byte.
- in ax,dx ;read ch#7 voltage.
- cmp ax,1024 ;is it > "1024"?
- jl wait_synch ;if not, try again.
- ;
- ;now that a synch pulse has been received, we can collect data
- ;
- get_data: mov cx,640 ;cx will count loops.
- mov si,0 ;si=array offset pointer.
- mov bx,array ;bx=array base pointer.
- mov dx,0714H ;point at control byte.
- mov al,10000100B ;enable external starts and
- out dx,al ;disable autoincrementing.
- inc dx ;point dx at 0715H.
- in ax,dx ;read data to clear "done"bit.
- mov al,0
- out dx,al ;specify a/d channel #0.
- data_loop: dec dx ;point at status byte
- in_loop: in al,dx ;and get it.
- cmp al,10000000B ;is bit 7 set?
- jb in_loop ;no, try again.
- inc dx ;point at 0715h.
- in ax,dx ;get data word and
- add [bx][si],ax ;add it to array.
- add si,2 ;point si at next array element.
- loop data_loop ;and loop back if 640 pts haven't
- ;been collected, i.e., if cx>0.
- dec dx ;point at control byte.
- mov al,10000000B ;disable autostart.
- out dx,al
- ;
- call beep ;beep speaker.
- ;
- ;put "x" plus 2 spaces on screen to indicate sweep.
- ;
- push ax ;save registers.
- push bx
- push bp
- mov bh,0 ;select display page.
- mov al,120 ;character "x".
- mov ah,14 ;write, advance cursor.
- int 10H
- mov ah,14
- mov al,32 ;character " ".
- int 10H
- mov ah,14
- mov al,32 ;character " ".
- int 10H
- pop bp ;restore registers.
- pop bx
- pop ax
- ;
- jmp synch_loop ;go wait for another pulse.
- ;
- done: nop
- ;
- ;now go back thru array dividing by # sweeps.
- ;
- mov si,[bp]+6
- mov dx,[si] ;now dx has # sweeps.
- mov nswps,dx ;now nswps has # sweeps.
- mov si,0
- mov cx,640 ;cx will count loops.
- div_loop: mov ax,[bx][si] ;move array element to ax.
- cwd ;convert to dbl word.
- idiv nswps ;divide by # sweeps.
- mov [bx][si],ax ;put quotient back in array.
- add si,2 ;point at next array element.
- loop div_loop ;loop back if all not done.
- ;
- pop bp ;restore bp.
- sti
- ret 4
- dscope1 endp
- ;
- ;this subroutine "beep" plays a tone on the speaker - desired duration
- ;(in milliseconds) and frequency (in Hz) are placed in bx
- ;and di, respectively.
- ;
- beep proc
- push ax ;save registers.
- push bx
- push cx
- push dx
- push di
- mov di,500 ;set frequency.
- mov bx,50 ;set duration to 50 msec.
- mov al,0B6H ;write control byte to timer mode reg.
- out 43H,al
- mov dx,14H ;to get desired freq, we must send
- mov ax,4F38H ;the value 1331000/freq to timer 2.
- div di
- out 42H,al ;write low byte to timer 2.
- mov al,ah
- out 42H,al ;write high byte to timer 2.
- in al,61H ;get current timer port setting.
- mov ah,al ;save it in ah.
- or al,3 ;change bits 0 and 1 and send to timer
- out 61H,al ;port, which turns speaker on.
- hold_it: mov cx,280 ;wait 1 msec.
- beeping: loop beeping ;this loop cycles 280 times in one
- ;msec.
- dec bx ;has the count expired?
- jnz hold_it ;if not, go back for another msec.
- mov al,ah ;recover port value.
- out 61H,al ;speaker off.
- pop di ;restore reg.
- pop dx
- pop cx
- pop bx
- pop ax
- ret
- beep endp
- ;
- cseg ends
- end
- ;